import React, {
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from "react";
import Scrollbars from "react-custom-scrollbars";
import update from "immutability-helper";
import { PlusCircleOutlined } from "@ant-design/icons";
import { Button, Tabs, Form, Modal } from "antd";
import ReactJson from "react-json-view";
import DndFormCtx, { genGroup, genCard, getInitValues } from "../core";
import Card from "./card";
import Buttons from "./buttons";
import Interpreter from "../interpreter";

import styles from "./index.module.less";

const { TabPane } = Tabs;

const FunDesginBord = () => {
  const { instance, updateInstance, setActivedElement } =
    useContext(DndFormCtx);

  const [activeKey, setActiveKey] = useState(instance.groups[0].uuid);

  const [view, openView] = useState(false);

  useEffect(() => {
    const groupIndex = instance.groups.findIndex((g) => g.uuid === activeKey);
    if (groupIndex > -1) {
      setActivedElement({
        element: instance.groups[groupIndex],
        position: { groupIndex, cardIndex: 0, rowIndex: 0, colIndex: 0 },
      });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [activeKey]);

  const preView = useCallback(() => {
    const errorInfo = getInitValues(instance).erroInfo;
    if (errorInfo.length > 0) {
      Modal.error({
        title: "配置错误",
        width: "450px",
        content: (
          <div>
            {errorInfo.map((t, i) => (
              <p key={i}>{t}</p>
            ))}
          </div>
        ),
      });
    } else {
      openView(true);
    }
  }, [instance]);

  const preJson = useCallback(() => {
    Modal.info({
      title: "json格式",
      width: 800,
      content: (
        <div style={{ height: 400 }}>
          <Scrollbars>
            <ReactJson src={instance}></ReactJson>
          </Scrollbars>
        </div>
      ),
    });
  }, [instance]);
  return (
    <Scrollbars>
      <div className={styles.main}>
        <Form>
          <Tabs
            type="editable-card"
            activeKey={activeKey}
            onChange={(key: string) => {
              setActiveKey(key);
            }}
            onEdit={(key, action) => {
              if (action === "add") {
                const newGroup = genGroup("新分区" + instance.groups.length);
                updateInstance(
                  update(instance, {
                    groups: {
                      $push: [newGroup],
                    },
                  })
                );
                setActiveKey(newGroup.uuid);
              } else if (action === "remove") {
                Modal.confirm({
                  content: "是否删除？",
                  onOk() {
                    const idx = instance.groups.findIndex(
                      (g) => g.uuid === key
                    );
                    updateInstance(
                      update(instance, {
                        groups: {
                          $splice: [[idx, 1]],
                        },
                      })
                    );
                    if (activeKey === key) {
                      let next =
                        instance.groups[idx - 1] ?? instance.groups[idx + 1];
                      setActiveKey(next.uuid);
                    }
                  },
                });
              }
            }}
            tabBarExtraContent={
              <div className={styles.tabsAction}>
                <Button type="link" onClick={preView}>
                  预览
                </Button>
                <Button type="link" onClick={preJson}>
                  JSON
                </Button>
              </div>
            }
          >
            {instance.groups.map((group, gIndex) => {
              return (
                <TabPane
                  key={group.uuid}
                  tab={
                    <div
                      onClick={() => {
                        setActivedElement({
                          element: group,
                          position: {
                            groupIndex: gIndex,
                            cardIndex: 0,
                            rowIndex: 0,
                            colIndex: 0,
                          },
                        });
                      }}
                    >
                      {group.title}
                    </div>
                  }
                  closable={instance.groups.length > 1}
                >
                  <div className={styles.group}>
                    {group.cards.map((card, cIndex, { length }) => {
                      return (
                        <Card
                          info={card}
                          couldDelete={length > 1}
                          couldMoveUp={cIndex !== 0}
                          couldMoveDown={cIndex !== length - 1}
                          key={card.uuid}
                          gIndex={gIndex}
                          cIndex={cIndex}
                        ></Card>
                      );
                    })}
                    <Button
                      icon={<PlusCircleOutlined />}
                      type="primary"
                      onClick={() => {
                        const newCard = genCard(`新分组${group.cards.length}`);
                        updateInstance(
                          update(instance, {
                            groups: {
                              [gIndex]: {
                                cards: {
                                  $push: [newCard],
                                },
                              },
                            },
                          })
                        );
                      }}
                    >
                      新建分组
                    </Button>
                  </div>
                </TabPane>
              );
            })}
          </Tabs>

          <Buttons />
        </Form>
      </div>

      <Modal
        getContainer="body"
        title="预览"
        width="auto"
        visible={view}
        onCancel={() => openView(false)}
        onOk={() => openView(false)}
      >
        {useMemo(
          () => (
            <Interpreter schema={instance} />
          ),
          [instance]
        )}
      </Modal>
    </Scrollbars>
  );
};

export default FunDesginBord;
